Imports System.Security.Cryptography

Public Class Hash
    '***********************************************
    ' Private Variables
    '***********************************************
    Private mbytHashType As MyHashType
    Private mstrOriginalString As String
    Private mstrHashString As String
    Private mhash As HashAlgorithm

    Private mboolUseSalt As Boolean
    Private mstrSaltValue As String = String.Empty
    Private msrtSaltLength As Short = 8


    Public Enum MyHashType As Byte
        MD5
        SHA1
        SHA256
        SHA384
        SHA512
    End Enum

#Region "Public Properties"
    Property HashType() As MyHashType
        Get
            Return mbytHashType
        End Get
        Set(ByVal Value As MyHashType)
            If mbytHashType <> Value Then
                mbytHashType = Value
                mstrOriginalString = String.Empty
                mstrHashString = String.Empty

                Me.SetEncryptor()
            End If
        End Set
    End Property

    Property SaltValue() As String
        Get
            Return mstrSaltValue
        End Get
        Set(ByVal Value As String)
            mstrSaltValue = Value
        End Set
    End Property

    Property SaltLength() As Short
        Get
            Return msrtSaltLength
        End Get
        Set(ByVal Value As Short)
            msrtSaltLength = Value
        End Set
    End Property

    Property UseSalt() As Boolean
        Get
            Return mboolUseSalt
        End Get
        Set(ByVal Value As Boolean)
            mboolUseSalt = Value
        End Set
    End Property

    Property HashObject() As HashAlgorithm
        Get
            Return mhash
        End Get
        Set(ByVal Value As HashAlgorithm)
            mhash = Value
        End Set
    End Property

    Property OriginalString() As String
        Get
            Return mstrOriginalString
        End Get
        Set(ByVal Value As String)
            mstrOriginalString = Value
        End Set
    End Property

    Property HashString() As String
        Get
            Return mstrHashString
        End Get
        Set(ByVal Value As String)
            mstrHashString = Value
        End Set
    End Property
#End Region

#Region "Constructors"
    Public Sub New()
        ' Set Default Hash Type
        mbytHashType = HashType.MD5
    End Sub

    Public Sub New(ByVal HashType As MyHashType)
        mbytHashType = HashType
    End Sub

    Public Sub New(ByVal HashType As MyHashType, _
      ByVal OriginalString As String)
        mbytHashType = HashType
        mstrOriginalString = OriginalString
    End Sub

    Public Sub New(ByVal HashType As MyHashType, _
      ByVal OriginalString As String, _
      ByVal UseSalt As Boolean, _
      ByVal SaltValue As String)
        mbytHashType = HashType
        mstrOriginalString = OriginalString
        mboolUseSalt = UseSalt
        mstrSaltValue = SaltValue
    End Sub
#End Region

#Region "SetEncryptor() Method"
    Private Sub SetEncryptor()
        Select Case mbytHashType
            Case HashType.MD5
                mhash = New MD5CryptoServiceProvider

            Case HashType.SHA1
                mhash = New SHA1CryptoServiceProvider

            Case HashType.SHA256
                mhash = New SHA256Managed

            Case HashType.SHA384
                mhash = New SHA384Managed

            Case HashType.SHA512
                mhash = New SHA512Managed

        End Select
    End Sub
#End Region

#Region "CreateHash() Methods"
    Public Function CreateHash() As String
        Dim bytValue() As Byte
        Dim bytHash() As Byte

        ' Create New Crypto Service Provider Object
        SetEncryptor()

        ' Check to see if we will Salt the value
        If mboolUseSalt Then
            If mstrSaltValue.Length = 0 Then
                mstrSaltValue = Me.CreateSalt()
            End If
        End If

        ' Convert the original string to array of Bytes
        bytValue = System.Text.Encoding. _
          UTF8.GetBytes(mstrSaltValue & mstrOriginalString)

        ' Compute the Hash, returns an array of Bytes
        bytHash = mhash.ComputeHash(bytValue)

        ' Return a base 64 encoded string of the Hash value
        Return Convert.ToBase64String(bytHash)
    End Function

    Public Function CreateHash( _
      ByVal OriginalString As String) As String
        mstrOriginalString = OriginalString

        Return Me.CreateHash()
    End Function

    Public Function CreateHash( _
      ByVal OriginalString As String, _
      ByVal HashType As MyHashType) As String
        mstrOriginalString = OriginalString
        mbytHashType = HashType

        Return Me.CreateHash()
    End Function

    Public Function CreateHash( _
    ByVal OriginalString As String, _
    ByVal UseSalt As Boolean) As String
        mstrOriginalString = OriginalString
        mboolUseSalt = UseSalt

        Return Me.CreateHash()
    End Function

    Public Function CreateHash( _
      ByVal OriginalString As String, _
      ByVal HashType As MyHashType, _
      ByVal UseSalt As Boolean) As String
        mstrOriginalString = OriginalString
        mbytHashType = HashType
        mboolUseSalt = UseSalt

        Return Me.CreateHash()
    End Function

    Public Function CreateHash( _
      ByVal OriginalString As String, _
      ByVal HashType As MyHashType, _
      ByVal SaltValue As String) As String
        mstrOriginalString = OriginalString
        mbytHashType = HashType
        mstrSaltValue = SaltValue

        Return Me.CreateHash()
    End Function

    Public Function CreateHash( _
      ByVal OriginalString As String, _
      ByVal SaltValue As String) As String
        mstrOriginalString = OriginalString
        mstrSaltValue = SaltValue

        Return Me.CreateHash()
    End Function
#End Region

#Region "Misc. Routines"
    Public Sub Reset()
        mstrSaltValue = String.Empty
        mstrOriginalString = String.Empty
        mstrHashString = String.Empty
        mboolUseSalt = False
        mbytHashType = HashType.MD5

        mhash = Nothing
    End Sub

    Public Function CreateSalt() As String
        Dim bytSalt(msrtSaltLength) As Byte
        Dim rng As New RNGCryptoServiceProvider

        rng.GetBytes(bytSalt)

        Return Convert.ToBase64String(bytSalt)
    End Function
#End Region
End Class
